﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;

namespace PokeTD
{
    class Highscore
    {
        public static int user_id = 1;
        public static string HighscoreName = "";

        static Highscore()
        {
            if (!isHighscoreAPIAvailable())
                return;

            Assembly assembly = Assembly.LoadFrom("HighscoreAPI.dll");
            Type LoginType = assembly.GetType("PokeTDHighscoreAPI.LoginType");
            MethodInfo read = LoginType.GetMethod("GetName");
            HighscoreName = (string)read.Invoke(null, new object[] { });
        }

        public static bool IsGuest()
        {
            if (user_id == 1)
                ReadUserId();
            return user_id <= 1;
        }

        public static void ReadUserId()
        {
            if (!isHighscoreAPIAvailable())
                return;

            Assembly assembly = Assembly.LoadFrom("HighscoreAPI.dll");
            Type LoginType = assembly.GetType("PokeTDHighscoreAPI.LoginType");
            MethodInfo read = LoginType.GetMethod("ReadUserID");
            user_id = (int)read.Invoke(null, new object[] { });
        }

        public static bool LoginUser(string mail, string password, bool keep)
        {
            if (!isHighscoreAPIAvailable())
                return false;

            Assembly assembly = Assembly.LoadFrom("HighscoreAPI.dll");
            Type LoginType = assembly.GetType("PokeTDHighscoreAPI.LoginType");
            MethodInfo verify = LoginType.GetMethod("VerifyLogin");
            user_id = (int)verify.Invoke(null, new object[] { mail, password });

            if (user_id <= 1)
                return false;

            if (keep)
            {
                MethodInfo save = LoginType.GetMethod("SaveUserID");
                save.Invoke(null, new object[] { user_id });
            }

            return true;
        }

        /// <summary>
        /// Tests, whether the Highscore DLL is available
        /// </summary>
        /// <returns>true/false</returns>
        public static bool isHighscoreAPIAvailable()
        {
            return File.Exists("HighscoreAPI.dll");
        }
        public static int submitHighscore(int userid, string username, int score, string data = "")
        {
            if (!isHighscoreAPIAvailable())
                return -1;

            if (user_id == 1)
                ReadUserId();

            Assembly assembly = Assembly.LoadFrom("HighscoreAPI.dll");
            Type HighscoreAccess = assembly.GetType("PokeTDHighscoreAPI.HighscoreAccess");
            Type HighscoreEntry = assembly.GetType("HighscoreReader.HighscoreEntry");
            MethodInfo info = HighscoreAccess.GetMethod("Submit");

            object entry = Activator.CreateInstance(HighscoreEntry);
            HighscoreEntry.GetField("highscore_score").SetValue(entry, score);
            HighscoreEntry.GetField("highscore_guestname").SetValue(entry, username);
            HighscoreEntry.GetField("highscore_member").SetValue(entry, userid);
            if (data != "")
                HighscoreEntry.GetField("highscore_data").SetValue(entry, data);

            object Reader = Activator.CreateInstance(HighscoreAccess);
            if ((bool)info.Invoke(Reader, new object[1] { entry }))
            {
                return -1;
            }

            return 0;
        }

        public static HighscoreEntry[] getHighscore()
        {
            if (!isHighscoreAPIAvailable())
                return null;

            Assembly assembly = Assembly.LoadFrom("HighscoreAPI.dll");
            Type HighscoreAccess = assembly.GetType("PokeTDHighscoreAPI.HighscoreAccess");
            MethodInfo MethodGet = HighscoreAccess.GetMethod("Get");
            Type HighscoreData = assembly.GetType("HighscoreReader.HighscoreData");
            Type HighscoreEntry = assembly.GetType("HighscoreReader.HighscoreEntry");

            object HighscoreReader = Activator.CreateInstance(HighscoreAccess);
            object data = MethodGet.Invoke(HighscoreReader, new object[0]);
            FieldInfo[] fields = HighscoreData.GetFields();
            object list = HighscoreData.GetField("list").GetValue(data);
            object values = list.GetType().GetMethod("get_Values").Invoke(list, new object[0]);

            int count = (int)values.GetType().GetMethod("get_Count").Invoke(values, new object[0]);
            HighscoreEntry[] Result = new HighscoreEntry[count];

            MethodInfo[] m = list.GetType().GetMethods();

            for (int i = 0; i < count; i++)
            {
                object entry;
                try
                {
                    entry = list.GetType().GetMethod("get_Item").Invoke(list, new object[1] { i + 1 });
                }
                catch (Exception)
                {
                    continue;
                }
                Result[i] = new HighscoreEntry();
                Result[i].highscore_id = (int)HighscoreEntry.GetField("highscore_id").GetValue(entry);
                Result[i].highscore_game = (int)HighscoreEntry.GetField("highscore_game").GetValue(entry);
                Result[i].highscore_member = (int)HighscoreEntry.GetField("highscore_member").GetValue(entry);
                Result[i].highscore_guestname = (string)HighscoreEntry.GetField("highscore_guestname").GetValue(entry);
                Result[i].highscore_score = (int)HighscoreEntry.GetField("highscore_score").GetValue(entry);
                Result[i].highscore_log_ip = (string)HighscoreEntry.GetField("highscore_log_ip").GetValue(entry);
                Result[i].highscore_log_time = (int)HighscoreEntry.GetField("highscore_log_time").GetValue(entry);
                Result[i].user_id = (int)HighscoreEntry.GetField("user_id").GetValue(entry);
                Result[i].username = (string)HighscoreEntry.GetField("username").GetValue(entry);
                Result[i].user_colour = (string)HighscoreEntry.GetField("user_colour").GetValue(entry);
                Result[i].user_avatar_mini = (string)HighscoreEntry.GetField("user_avatar_mini").GetValue(entry);
                Result[i].highscore_data = (string)HighscoreEntry.GetField("highscore_data").GetValue(entry);
            }

            return Result;
        }
    }
}
